/**
 * Filename: GAMutableSet.js
 * Author: Ameer Sheikh
 * Date Created: 2011-09-19
 * Date Updated: 2011-09-19
 * Change Log : (most recent first)
 * 
 * 
 */

exports.GAMutableSet = Core.Class.subclass({

    classname: 'GAMutableSet',

    initialize: function() {
		//this._privateDict = {};
		this._privateDict = new GAMutableDictionary();
    },
    
	
    initWithSet: function(someSet)
    {
    	var someDictionary = someSet._getDictionary()
    	this._getDictionary().initWithDictionary(someDictionary);
    },
    
    cardinality: function()
    {
    	return this._privateDict.allKeys().length;
    },
    
	addObject:function(someObj) //throws exception
	{
		try
		{
			if(!(Core.ObjectRegistry.isObjectRegistered(someObj)))
			{
				Core.ObjectRegistry.register(someObj);
				TAUtil.log(someObj+' added to ObjectRegistry');				
			}
		}
		catch(exception)
		{
			console.log(exception);
		}
		if(Core.ObjectRegistry.isObjectRegistered(someObj))
		{
			var key = Core.ObjectRegistry.objectToId(someObj) + '';
			if (!(this.doesObjectExist(someObj)))
			{
				this._privateDict.setObject(key, someObj);
			}			
		}
		else
		{
			throw new Error('Object not added into GAMutableSet');
		}
	},
	
	arrayOfObjects: function()
	{
		return this._privateDict.allValues();
	},
	
	doesObjectExist: function(someObject)
	{
		var key = Core.ObjectRegistry.objectToId(someObject) + '';
		if(this._privateDict.hasKey(key))
		{
			return true;
		}
		return false;
	},
	
	removeObject:function(object) 
	{
		var key = Core.ObjectRegistry.objectToId(object) + '';
		this._privateDict.removeObjectForKey(key);
	},
	
	
	addObjectsFromArray: function(array)
	{
		for (var i = 0; i < array.length; i++)
		{
			var obj = array[i];
			this.addObject(obj);
		}
	},
	
	minusSet: function(otherSet)
	{
		var otherDict = otherSet._getDictionary();
		var keys = otherDict.allKeys();
		for ( var i = 0; i < keys.length; i++)
		{
			this._removeObjectForKey(keys[i]);
		}
	},
	
	unionSet: function(otherSet)
	{
		var otherDict = otherSet._getDictionary();
		var allKeys = otherDict.allKeys();
		for ( var i = 0; i < allKeys.length; i++)
		{
			var key = allKeys[i];
			if( !(this._doesKeyExist(key)) )
			{
				this.addObject(otherDict.objectForKey(key));
			}
		}
	},
	
	
	intersectSet: function(otherSet)
	{
		var allKeys = this._privateDict.allKeys();		
		for ( var i = (allKeys.length - 1); i >=0 ; i--)
		{
			var key = allKeys[i];
			if( !(otherSet._doesKeyExist(key)) )
			{
				TAUtil.log("element with key: "+key+" removed!");
				this._removeObjectForKey(key);
			}
			else
			{
				console.log('Object existing in both sets: Key ' +key +' and value is ' +this._privateDict.objectForKey(key) + ' and: '+ otherSet._getDictionary().objectForKey(key));
			}
		}
	},
	
	
	removeAllObjects: function()
	{
		this._privateDict.removeAllObjects();
	},
	
	setSet: function(someSet)
	{
		this.removeAllObjects();
		this.initWithSet(someSet);
	},
	
	toString: function()
	{
		var str = '(';
		var key = '';
		var allKeys = this._privateDict.allKeys();
		if(allKeys.length <= 0)
		{
			return '<EMPTY>';
		}
		for ( var i = 0; i < (allKeys.length - 1); i++)
		{
			key = allKeys[i];
			str += this._privateDict.objectForKey(key) + ', ';
		}
		key = allKeys[i];
		str += this._privateDict.objectForKey(key) + ')';
		return str;
	},
	
	print: function()
	{
		var str = this.toString();
		TAUtil.log('GAMutableSet: '+str);
	},
	
	destroy:function()
	{
		this.removeAllObjects();
		this._privateDict.destroy();
		this._privateDict = null;
	},
	
	_removeObjectForKey:function(key) 
	{
		this._privateDict.removeObjectForKey(key);
	},
	
	_doesKeyExist: function(someKey)
	{
		if(this._privateDict.hasKey(someKey))
		{
			return true;
		}
		return false;
	},
	
	_getDictionary: function()
    {
    	return this._privateDict;
    }
    
});
